Merge branch 'master' into ospath
authorJoey Hess <joeyh@joeyh.name>
Wed, 29 Jan 2025 18:24:35 +0000 (14:24 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 29 Jan 2025 18:29:34 +0000 (14:29 -0400)
1  2 
Utility/OsPath.hs

index b487a2976d41cb395800e1542d24be7b6c2e5af8,9fa4e0f57e57088a9e509112089eec13ec34005f..0af093da92b0ceeb0c00df13b1de7bdf5b1edc46
@@@ -23,81 -17,49 +23,98 @@@ module Utility.OsPath 
  ) where
  
  import Utility.FileSystemEncoding
 -
 +import Data.ByteString.Short (ShortByteString)
 +import qualified Data.ByteString.Short as S
  #ifdef WITH_OSPATH
 +import System.OsPath as X hiding (OsPath, OsString, unsafeFromChar)
  import System.OsPath
  import "os-string" System.OsString.Internal.Types
 -import qualified Data.ByteString.Short as S
 +import qualified System.FilePath.ByteString as PB
+ #if defined(mingw32_HOST_OS)
+ import GHC.IO (unsafePerformIO)
+ import System.OsString.Encoding.Internal (cWcharsToChars_UCS2)
+ import qualified System.OsString.Data.ByteString.Short.Word16 as BS16
+ #endif
 +#else
 +import System.FilePath.ByteString as X hiding (RawFilePath, getSearchPath)
 +import System.FilePath.ByteString (getSearchPath)
 +import Data.ByteString (ByteString)
 +import Data.Char
 +import Data.Word
 +#endif
 +
 +class OsPathConv t where
 +      toOsPath :: t -> OsPath
 +      fromOsPath :: OsPath -> t
 +
 +instance OsPathConv FilePath where
 +      toOsPath = toOsPath . toRawFilePath
 +      fromOsPath = fromRawFilePath . fromOsPath
 +
 +#ifdef WITH_OSPATH
 +instance OsPathConv RawFilePath where
 +      toOsPath = bytesToOsPath . S.toShort
++#if defined(mingw32_HOST_OS)
++      fromOsPath = bytesFromOsPath
++#else
 +      fromOsPath = S.fromShort . bytesFromOsPath
++#endif
 +
 +instance OsPathConv ShortByteString where
 +      toOsPath = bytesToOsPath
++#if defined(mingw32_HOST_OS)
++      fromOsPath = S.toShort . bytesFromOsPath
++#else
 +      fromOsPath = bytesFromOsPath
++#endif
  
- {- Unlike System.OsString.fromBytes, on Windows this does not ensure a
-  - valid USC-2LE encoding. The input ByteString must be in a valid encoding
-  - already or uses of the OsPath will fail. -}
 -toOsPath :: RawFilePath -> OsPath
 +bytesToOsPath :: ShortByteString -> OsPath
  #if defined(mingw32_HOST_OS)
- bytesToOsPath = OsString . WindowsString
+ -- On Windows, OsString contains a ShortByteString that is
+ -- utf-16 encoded. So have to convert the input to that.
+ -- This is relatively expensive.
 -toOsPath = unsafePerformIO . encodeFS . fromRawFilePath
++bytesToOsPath = unsafePerformIO . encodeFS . fromRawFilePath
  #else
 -toOsPath = OsString . PosixString . S.toShort
 +bytesToOsPath = OsString . PosixString
  #endif
  
- bytesFromOsPath :: OsPath -> ShortByteString
 -fromOsPath :: OsPath -> RawFilePath
  #if defined(mingw32_HOST_OS)
- bytesFromOsPath = getWindowsString . getOsString
++bytesFromOsPath :: OsPath -> RawFilePath
+ -- On Windows, OsString contains a ShortByteString that is
+ -- utf-16 encoded. So have to convert the input from that.
+ -- This is relatively expensive.
 -fromOsPath = toRawFilePath . cWcharsToChars_UCS2 . BS16.unpack . getWindowsString
++bytesFromOsPath = toRawFilePath . cWcharsToChars_UCS2 . BS16.unpack . getWindowsString
  #else
 -fromOsPath = S.fromShort . getPosixString . getOsString
++bytesFromOsPath :: OsPath -> ShortByteString
 +bytesFromOsPath = getPosixString . getOsString
  #endif
  
 +{- For some reason not included in System.OsPath -}
 +getSearchPath :: IO [OsPath]
 +getSearchPath = map toOsPath <$> PB.getSearchPath
 +
 +{- Used for string constants. -}
 +literalOsPath :: ShortByteString -> OsPath
 +literalOsPath = bytesToOsPath
 +
  #else
 -{- When not building with WITH_OSPATH, use FilePath. This allows
 - - using functions from legacy FilePath libraries interchangeably with
 - - newer OsPath libraries.
 +{- When not building with WITH_OSPATH, use RawFilePath.
   -}
 -type OsPath = FilePath
 +type OsPath = RawFilePath
 +
 +type OsString = ByteString
 +
 +instance OsPathConv RawFilePath where
 +      toOsPath = id
 +      fromOsPath = id
  
 -type OsString = String
 +instance OsPathConv ShortByteString where
 +      toOsPath = S.fromShort
 +      fromOsPath = S.toShort
  
 -toOsPath :: RawFilePath -> OsPath
 -toOsPath = fromRawFilePath
 +unsafeFromChar :: Char -> Word8
 +unsafeFromChar = fromIntegral . ord
  
 -fromOsPath :: OsPath -> RawFilePath
 -fromOsPath = toRawFilePath
 +literalOsPath :: RawFilePath -> OsPath
 +literalOsPath = id
  #endif